<template>
    <el-form-item :label="$t('shop.deliveryTemplate.billing_method')" required>
        <el-radio-group v-model="state.type" size="large" @change="updateBillingMethod">
            <el-radio-button v-for="(label, value) in billingMethod" :key="value" :value="value" :label="value">
                {{ label }}
            </el-radio-button>
        </el-radio-group>
    </el-form-item>
    <el-form-item :label="$t('shop.deliveryTemplate.delivery_template_detail')" required>
        <el-table class="table" border :data="state.tableData" v-loading="tableLoading">
            <el-table-column prop="area_name" :label="t('shop.deliveryTemplate.delivery_area')" header-align="center" min-width="280">
                <template #default="scope">
                    {{ scope.row.area_name }}
                    <div class="operate">
                        <Icon name="el-icon-Edit" class="operate-button" @click="editRegion(scope.$index)" />
                        <el-popconfirm
                            :title="t('shop.deliveryTemplate.Are you sure to delete')"
                            class="operate-button"
                            :hide-after="0"
                            @confirm="deleteRegion(scope.$index)"
                        >
                            <template #reference>
                                <Icon name="el-icon-Delete" class="operate-button" />
                            </template>
                        </el-popconfirm>
                    </div>
                </template>
            </el-table-column>
            <el-table-column prop="first" :label="tableHeaderColumn.first_column" :min-width="145" align="center">
                <template #header="{ column }">
                    <el-tooltip :content="column.label" placement="top"> {{ column.label }}</el-tooltip>
                </template>
                <template #default="scope">
                    <el-input-number :min="1" :precision="0" size="small" v-model="scope.row.first"></el-input-number>
                </template>
            </el-table-column>
            <el-table-column prop="first_price" :label="t('shop.deliveryTemplate.freight')" :min-width="145" align="center">
                <template #header="{ column }">
                    <el-tooltip :content="column.label" placement="top"> {{ column.label }}</el-tooltip>
                </template>
                <template #default="scope">
                    <el-input-number :min="0" size="small" :precision="2" v-model="scope.row.first_price"></el-input-number>
                </template>
            </el-table-column>
            <el-table-column prop="continue" :label="tableHeaderColumn.continue_column" :min-width="145" align="center">
                <template #header="{ column }">
                    <el-tooltip :content="column.label" placement="top"> {{ column.label }}</el-tooltip>
                </template>
                <template #default="scope">
                    <el-input-number :min="0" :precision="0" size="small" v-model="scope.row.continue"></el-input-number>
                </template>
            </el-table-column>
            <el-table-column prop="continue_price" :label="t('shop.deliveryTemplate.continue_freight')" :min-width="145" align="center">
                <template #header="{ column }">
                    <el-tooltip :content="column.label" placement="top"> {{ column.label }}</el-tooltip>
                </template>
                <template #default="scope">
                    <el-input-number :min="0" size="small" :precision="2" v-model="scope.row.continue_price"></el-input-number>
                </template>
            </el-table-column>
        </el-table>
        <el-button class="add-region" @click="addRegion">
            <Icon name="el-icon-AddLocation" />
            <span>{{ $t('shop.deliveryTemplate.add_delivery_area') }}</span>
        </el-button>
    </el-form-item>

    <!-- 区域弹窗 -->
    <el-dialog class="ba-operate-dialog" v-model="showRegion" :close-on-click-modal="false" width="50%" append-to-body>
        <template #header>
            <div class="title" v-drag="['.ba-operate-dialog', '.el-dialog__header']" v-zoom="'.ba-operate-dialog'">
                {{ subType == 'add' ? t('Add') : t('Edit') }}
            </div>
        </template>
        <el-scrollbar v-loading="loadingRegion" class="ba-table-form-scrollbar">
            <div :style="config.layout.shrink ? '' : 'width: calc(100% - ' + baTable.form.labelWidth! / 2 + 'px)'">
                <el-tree
                    class="region-tree"
                    ref="treeRef"
                    v-model="treeValue"
                    :data="treeData"
                    :props="defaultProps"
                    multiple
                    :render-after-expand="false"
                    show-checkbox
                    accordion
                    node-key="id"
                    :default-checked-keys="selectAreaIds"
                    :key="selectAreaIds.join(',')"
                />
            </div>
        </el-scrollbar>
        <template #footer>
            <div :style="'width: calc(100% - ' + baTable.form.labelWidth! / 1.8 + 'px)'">
                <div class="dialog-footer">
                    <div class="action">
                        <div>
                            <el-button type="info" v-show="selectAll" @click="handleCancelSelectAll">
                                {{ $t('shop.lang.cancelSelectAll') }}
                            </el-button>
                            <el-button type="success" v-show="treeData.length > 0 && !selectAll" @click="handleSelectAll">
                                {{ $t('shop.lang.selectAll') }}
                            </el-button>
                        </div>
                        <div>
                            <el-button type="danger" @click="showRegion = false">{{ t('Cancel') }}</el-button>
                            <el-button type="primary" @click="onSubmitRegion()">{{ t('Save') }}</el-button>
                        </div>
                    </div>
                </div>
            </div>
        </template>
    </el-dialog>
</template>
<script setup lang="ts">
import { watchEffect, onMounted, watch, computed } from 'vue'
import { ref } from 'vue'
import { getTemplate } from '/@/api/backend/shop/delivery/delivery'
import { ElTree, ElMessage } from 'element-plus'
import { deliveryResult, areaResult } from './deliveryTemplate'
import Icon from '/@/components/icon/index.vue'
import { useI18n } from 'vue-i18n'
import { useConfig } from '/@/stores/config'
import type baTableClass from '/@/utils/baTable'
import { inject } from 'vue'

const { t } = useI18n()

const config = useConfig()
const baTable = inject('baTable') as baTableClass

const defaultProps = {
    children: 'children',
    label: 'name',
}

interface Prop {
    modelValue: deliveryResult[]
    type: number | string
}
const props = withDefaults(defineProps<Prop>(), {
    modelValue: () => [],
    type: 1,
})
const state = ref({
    tableData: props.modelValue,
    type: Number(props.type || 1),
})

// 运费计算方式
const billingMethod = {
    1: t('shop.deliveryTemplate.by_num'),
    2: t('shop.deliveryTemplate.by_weight'),
    3: t('shop.deliveryTemplate.by_volumn'),
}

const treeData = ref<areaResult[]>([])
const emits = defineEmits<{
    (e: 'update:modelValue', value: object): void
    (e: 'update:type', value: number): void
}>()

const treeValue = ref([])
const showRegion = ref(false)

const tableHeaderColumn = ref({
    first_column: '',
    continue_column: '',
})

type TableHeader = {
    first_column: string
    continue_column: string
}
const tableHeader: { [key: number]: TableHeader } = {
    1: {
        first_column: t('shop.deliveryTemplate.first_num'),
        continue_column: t('shop.deliveryTemplate.continue_num'),
    },
    2: {
        first_column: t('shop.deliveryTemplate.first_weight'),
        continue_column: t('shop.deliveryTemplate.continue_weight'),
    },
    3: {
        first_column: t('shop.deliveryTemplate.first_volumn'),
        continue_column: t('shop.deliveryTemplate.continue_volumn'),
    },
}
//表头
watchEffect(() => {
    tableHeaderColumn.value = tableHeader[state.value.type]
})

//默认运费
const defaultFee = {
    first: 1,
    first_price: 0.0,
    continue: 0,
    continue_price: 0.0,
}

const selectAll = computed(() => {
    return selectAreaIds.value.length == treeData.value.map((item) => item.id).length
})
const handleSelectAll = () => {
    selectAreaIds.value = treeData.value.map((item) => item.id.toString())
}
const handleCancelSelectAll = () => {
    selectAreaIds.value = []
}

//区域选择弹窗
const loadingRegion = ref(false)
//获取区域数据
const getAllArea = () => {
    loadingRegion.value = true
    if (localStorage.getItem('deliveryArea')) {
        loadingRegion.value = false
        return JSON.parse(localStorage.getItem('deliveryArea')!)
    }
    getTemplate()
        .then((res) => {
            localStorage.setItem('deliveryArea', JSON.stringify(res.data))
            loadingRegion.value = false
            return res.data
        })
        .catch((error) => {
            console.error('Error fetching delivery area data:', error)
            loadingRegion.value = false
            return []
        })
}

//配送区域操作类型 add/edit
const subType = ref('add')
//区域数据索引
const subIndex = ref(0)
//已被选择的区域code
const selectAreaIds = ref<string[]>([])

//添加配送区域
const addRegion = () => {
    subType.value = 'add'
    showRegion.value = true
    //已被选择的区域
    const selectedArea = state.value.tableData.map((item) => item.area_id.split('|')).flat()
    filterSeltedArea(selectedArea)
    if (state.value.tableData.length == 0) {
        selectAreaIds.value = []
    } else {
        selectAreaIds.value = state.value.tableData.reduce((acc, item) => {
            const areas = item.area_id.split('|')
            areas.forEach((area) => {
                const [provinceId, cityCodeId] = area.split('-')
                acc.push(Number(cityCodeId) === 0 ? provinceId : cityCodeId)
            })
            return acc
        }, [] as string[])
    }
}

//编辑配送区域
const editRegion = (index: number) => {
    subType.value = 'edit'
    subIndex.value = index
    showRegion.value = true

    treeData.value = getAllArea()
    //当前已选择的区域
    const selectedArea = state.value.tableData
        .filter((item, i) => i !== index)
        .flatMap((item) => item.area_id.split('|'))
        .filter(Boolean)
    filterSeltedArea(selectedArea)
    //勾选选中的值
    selectAreaIds.value = state.value.tableData[index].area_id.split('|').map((item) => {
        const [provinceCode, cityCode] = item.split('-')
        return Number(cityCode) === 0 ? provinceCode : cityCode
    })
}

//过滤被选择的区域
const filterSeltedArea = (selectedArea: string[]) => {
    // 过滤掉已选择的区域
    getAllArea()
    selectedArea.forEach((area) => {
        //按-分割为省和市
        const [provinceCode, cityCode] = area.split('-')
        treeData.value = treeData.value.filter((item: areaResult) => {
            //过滤省份
            if (Number(cityCode) === 0) {
                return Number(item.id) !== Number(provinceCode)
            }
            //过滤城市
            item.children = item.children?.filter((item) => item.id != Number(cityCode))
            if (item.children) {
                return item.children.filter((item) => item.id != Number(cityCode)).length > 0
            }
            return true
        })
    })
}

//删除配送区域
const deleteRegion = (index: number) => {
    state.value.tableData.splice(index, 1)

    treeData.value = getAllArea()
}

//区域选择操作
const treeRef = ref<InstanceType<typeof ElTree>>()
const onSubmitRegion = () => {
    let selectedData = treeRef.value!.getCheckedNodes()

    if (selectedData.length == 0) return ElMessage({ message: t('shop.deliveryTemplate.Please select delivery area'), type: 'error' })

    const allCityData = JSON.parse(localStorage.getItem('deliveryArea')!).filter((item: areaResult) => item.level == 1)
    let alreadySetProvince: number[] = []
    let areaIdStr = ''

    selectedData.forEach((v) => {
        if (v.level == 1 && allCityData.find((item: areaResult) => item.id == v.id).children.length == v.children?.length) {
            //全省
            areaIdStr += `${v.id}-0|`
            alreadySetProvince.push(v.id)
        } else if (v.pid != 0) {
            if (!alreadySetProvince.includes(v.pid)) {
                areaIdStr += `${v.pid}-${v.id}|`
            }
        }
    })
    areaIdStr = areaIdStr.slice(0, -1)

    if (subType.value === 'add') {
        state.value.tableData.push(
            Object.assign(
                {
                    area_id: areaIdStr,
                    area_name: getAreaName(areaIdStr),
                },
                defaultFee
            )
        )
    } else {
        state.value.tableData[subIndex.value].area_id = areaIdStr
        state.value.tableData[subIndex.value].area_name = getAreaName(areaIdStr)
    }

    showRegion.value = false
    emits('update:modelValue', state.value.tableData)
}

// 获取区域名称
const getAreaName = (areaId: string) => {
    const areaIds = areaId.split('|')
    const provinces = treeData.value.filter((area) => area.level == 1)
    const cityMap = new Map()
    provinces.forEach((province) => {
        province.children?.forEach((city) => {
            cityMap.set(city.id, city.name)
        })
    })

    const provinceCityMap = new Map()
    areaIds.forEach((item) => {
        const [provinceId, cityId] = item.split('-')
        const province = provinces.find((province) => province.id == Number(provinceId))
        if (!province) return
        if (!provinceCityMap.has(province.name)) {
            provinceCityMap.set(province.name, [])
        }
        if (Number(cityId) == 0) {
            provinceCityMap.set(province.name, ['全省'])
        } else {
            provinceCityMap.get(province.name).push(cityMap.get(Number(cityId)))
        }
    })

    let areaStr = ''
    for (let [province, city] of provinceCityMap.entries()) {
        areaStr += `${province}(${city.join('、')})、`
    }
    return areaStr.slice(0, -1)
}

const updateBillingMethod = () => {
    emits('update:type', state.value.type)
}

const tableLoading = ref(false)
//进入组件时初始化区域数据
onMounted(async () => {
    tableLoading.value = true
    treeData.value = await getTemplate().then((res) => res.data)
    localStorage.setItem('deliveryArea', JSON.stringify(treeData.value))
    state.value.tableData.forEach((item) => {
        item.area_name = getAreaName(item.area_id)
    })
    tableLoading.value = false
})

watch(
    () => props.modelValue,
    (newVal) => {
        if (newVal) {
            newVal.forEach((item) => {
                item.first_price = Number(item.first_price)
                item.continue_price = Number(item.continue_price)
            })
            state.value.tableData = newVal
            treeData.value = getAllArea()
            emits('update:modelValue', state.value.tableData)
        }
    },
    { immediate: true, deep: true }
)
watch(
    () => props.type,
    (newVal) => {
        if (newVal) {
            state.value.type = Number(newVal)
            emits('update:type', state.value.type)
        }
    }
)
</script>

<style lang="scss" scoped>
.table {
    width: 100%;
}
.add-region {
    margin-top: 10px;
}
.operate {
    float: right;
    margin-top: 10px;

    &-button {
        cursor: pointer;
        margin: 5px;
    }
}
.dialog-footer .action {
    display: flex;
    justify-content: space-between;
}
</style>
